# -*- coding:utf-8 -*-

## =====================================================================
## Copyright (C) 2007-2011  Jean-Philippe GOLAY
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## =====================================================================


from Tkinter import *
import Pmw
from tkMessageBox import *

from Persistance import *
from iCalendar import CalendarGUI
from iNotes import NotesGUI
from iTax import TaxListGUI
from iReference import ReferenceListGUI


class CatalogueGUI(Toplevel):
	def __init__(self, parent=None, balloon=None, path=None, log=None):
		Toplevel.__init__(self, parent)
		self.parent=parent
		self.grab_set()
		self.transient(self.master)
		self.resizable(width=False, height=False)
		self.title(u"Catalogue")
		self.balloon=balloon
		self.imgSave=PhotoImage(file="img/save_icon.gif")
		self.imgDelete=PhotoImage(file="img/delete_icon.gif")
		self.imgCalendar=PhotoImage(file="img/calendar.gif")
		self.imgNotes=PhotoImage(file="img/edit.gif")
		self.imgSearch=PhotoImage(file="img/search_icon.gif")
		self.hoursListCB = Glob.HOURS_LIST
		self.minutesListCB = Glob.MINUTES_LIST
		self.path=path
		self.log=log
		# Afficher un icon personnalisé
		try:
			if os.name =="posix":
				img = PhotoImage(file=self.path+"/icons/Catalogue-icon.gif")
				self.tk.call("wm", "iconphoto", self._w, img)
			else:
				self.iconbitmap(default=self.path+"/icons/Catalogue-icon.gif")
		except TclError:
			self.log.warning("Le window manager ne supporte pas la jolie icône que je veux lui mettre... tant pis")
		self.log.info("\tCatalogueGUI\tStart")
		self.makeCatalogue()

	 # DEBUT de la gestion du module Catalogue ------------------------------------------------------------------------------------------------
	def clearFieldCatalogue(self):
		# Mise a zéro des champs
		self.catalogueValues[0].set("")
		self.catalogueValues[1].set("")
		self.catalogueValues[2].set("")
		self.listObject=[Catalogue,Reference,Tax]

	def selectCatalogue(self, event):
		if self.listCatalogue.get(0)!="":
			result = Catalogue.select(Catalogue.q.id==self.idListCatalogue[int(self.listCatalogue.curselection()[0])])
			for row in result:
				self.selectedCatalogue = row
			self.listObject[0]=self.selectedCatalogue
			if self.selectedCatalogue.name != None:self.catalogueValues[0].set(self.selectedCatalogue.name)
			if self.selectedCatalogue.dateIn != None:
				# Affichage de la date de Début (self.selectedCatalogue .dateIn)
				self.catalogueValues[1].set(self.selectedCatalogue.dateIn.strftime("%d/%m/%Y"))
			if self.selectedCatalogue.dateOut != None:
				# Affichage de la date de Fin (self.selectedCatalogue .dateOut)
				self.catalogueValues[2].set(self.selectedCatalogue.dateOut.strftime("%d/%m/%Y"))
			# activation du bouton supprimer
			self.deleteCatalogueBt.config(state=NORMAL)
			self.searchLineCatalogue()

	def searchCatalogue(self, event=None):
		if self.searchCatalogueValue.get() != "":
			self.listCatalogue.delete(0,END)
			self.idListCatalogue = []
			result = Catalogue.select(Catalogue.q.name.startswith(self.searchCatalogueValue.get().encode("utf-8")), orderBy=Catalogue.q.name)
			for row in result:
				self.listCatalogue.insert(END, row.name+" - du "+row.dateIn.strftime("%d/%m/%Y")+" au "+row.dateOut.strftime("%d/%m/%Y"))
				self.idListCatalogue.append(row.id)
		else:
			self.listCatalogue.delete(0,END)
			self.idListCatalogue = []
			result = Catalogue.select(orderBy=Catalogue.q.name)
			for row in result:
				self.listCatalogue.insert(END, row.name+" - du "+row.dateIn.strftime("%d/%m/%Y")+" au "+row.dateOut.strftime("%d/%m/%Y"))
				self.idListCatalogue.append(row.id)

	def makeCatalogue(self):
		topFrame = Frame(self)
		leftFrame = Frame(topFrame)
		# Fiche Catalogue  (présentation colonne de gauche)
		Label(leftFrame, text=u"Catalogue", ).pack(side=TOP, fill=X)
		# Création des champs a renseigner pour un object Catalogue
		catalogueLabels = (u"Nom", u"Début (date)", u"Fin (date)")
		self.catalogueValues = [StringVar(), StringVar(), StringVar()]
		count = 0
		for name in catalogueLabels:
			f = Frame(leftFrame)
			Label(f, width=12, text=name, anchor=W).pack(side=LEFT)
			if count == 1: # Date de Début
				Entry(f, textvariable=self.catalogueValues[count], width=27).pack(side=LEFT, fill=X)
				myCal1=Button(f, image=self.imgCalendar, command=lambda x=self.catalogueValues[count]:self.ctrlCalendar(x), padx=4, pady=1)
				myCal1.pack(side=LEFT)
				self.balloon.bind(myCal1, u"Calendrier")
			elif count == 2: # Date de Fin
				Entry(f, textvariable=self.catalogueValues[count], width=27).pack(side=LEFT, fill=X)
				myCal2=Button(f, image=self.imgCalendar, command=lambda x=self.catalogueValues[count]:self.ctrlCalendar(x), padx=4, pady=1)
				myCal2.pack(side=LEFT)
				self.balloon.bind(myCal2, u"Calendrier")
			else: 
				Entry(f, textvariable=self.catalogueValues[count], width=30).pack(side=LEFT, fill=X)
			f.pack(side=TOP, fill=X)
			count += 1
		# Boutons enregistrement (new ou modify) et suppression
		s = Frame(leftFrame) 
		self.saveCatalogueBt=Button(s, image=self.imgSave, command=self.createCatalogue)
		self.saveCatalogueBt.bind("<Return>", self.createCatalogue)
		self.saveCatalogueBt.pack(side=LEFT)
		self.balloon.bind(self.saveCatalogueBt, u"Enregistrer")
		self.deleteCatalogueBt=Button(s, image=self.imgDelete, command=self.deleteCatalogue, state=DISABLED)
		self.deleteCatalogueBt.bind("<Return>", self.deleteCatalogue)
		self.deleteCatalogueBt.pack(side=LEFT)
		self.balloon.bind(self.deleteCatalogueBt, u"Supprimer")
		s.pack(side=TOP, fill=X)
		leftFrame.pack(side=LEFT, fill=X)
		# Liste des Catalogue existants (présentation colonne de droite)
		rightFrame = Frame(topFrame) 
		Label(rightFrame, text=u"Liste des Catalogues").pack(side=TOP, fill=X)
		self.searchCatalogueValue = StringVar()
		self.searchCatalogueEt = Entry(rightFrame,  width=53, textvariable=self.searchCatalogueValue, relief=GROOVE)
		self.searchCatalogueEt.bind("<KeyRelease>", self.searchCatalogue)
		self.searchCatalogueEt.pack(side=TOP, fill=X)
		self.balloon.bind(self.searchCatalogueEt, u"Saisir les premières lettres d'une Catalogue\npour une recherche plus précise,\nla liste est classée par désignation.")
		s = Frame(rightFrame) 
		scrollbar = Scrollbar(s)
		scrollbar.pack(side=RIGHT, fill=Y)
		self.listCatalogue = Listbox(s)
		self.listCatalogue.config(yscrollcommand=scrollbar.set, width=50, selectmode=SINGLE, height=4)
		self.listCatalogue.bind("<ButtonRelease-1>",self.selectCatalogue)
		scrollbar.config(command=self.listCatalogue.yview)
		self.listCatalogue.pack(side=TOP, fill=X)
		self.balloon.bind(self.listCatalogue, u"Séléctionner un Catalogue\npour le visualiser ou le modifier.")
		s.pack(side=TOP, fill=X)
		rightFrame.pack(side=RIGHT, fill=BOTH)
		topFrame.pack(side=TOP, fill=X)
		self.makeLineCatalogue()
		# Initialisation
		self.clearFieldCatalogue()
		self.searchCatalogue()

	def getDateTimeInCatalogue(self):
		if self.catalogueValues[1].get() != "":
			date=self.catalogueValues[1].get().split("/")
			d = datetime.date(int(date[2]), int(date[1]), int(date[0]))
			return d
		else:
			return None

	def getDateTimeOutCatalogue(self):
		if self.catalogueValues[2].get() != "":
			date=self.catalogueValues[2].get().split("/")
			d = datetime.date(int(date[2]), int(date[1]), int(date[0]))
			return d
		else:
			return None

	def verifyCatalogue(self):
		if self.catalogueValues[0].get() == "":
			showerror(u"Erreur de saisie", u"Le champ Nom est obligatoire !\nMerci de le compléter.")
			return False
		elif self.catalogueValues[1].get() == "":
			showerror(u"Erreur de saisie", u"Le champ Début (date) est obligatoire !\nMerci de le compléter.")
			return False
		elif self.catalogueValues[2].get() == "":
			showerror(u"Erreur de saisie", u"Le champ Fin (date) est obligatoire !\nMerci de le compléter.")
			return False
		else:
			return True

	def createCatalogue(self, event=None):
		if self.verifyCatalogue():
			if  self.deleteCatalogueBt.config()["state"][4] == "normal":
				self.modifyCatalogue()
			else:
				if askyesno(u"Enregistrement", u"Souhaitez-vous enregistrer %s comme une nouvelle Catalogue ?\n" % self.catalogueValues[0].get()):
					Catalogue(name=self.catalogueValues[0].get().encode("utf-8"),
						dateIn=self.getDateTimeInCatalogue(),
						dateOut=self.getDateTimeOutCatalogue(),
						createDate=datetime.datetime.now()
					)
					self.searchCatalogue()
				self.clearFieldCatalogue()

	def modifyCatalogue(self, event=None):
		if askyesno(u"Modifier", u"Souhaitez-vous modifier la Catalogue %s ?" % str(self.selectedCatalogue.id)):
			self.selectedCatalogue.name=self.catalogueValues[0].get().encode("utf-8")
			self.selectedCatalogue.dateIn=self.getDateTimeInCatalogue()
			self.selectedCatalogue.dateOut=self.getDateTimeOutCatalogue()
			self.searchCatalogue()
		self.deleteCatalogueBt.config(state=DISABLED)
		self.clearFieldCatalogue()

	def deleteCatalogue(self, event=None):
		if askyesno(u"Suppression", u"Souhaitez-vous supprimer la Catalogue %s ?\nCette opération est irréversible !" % str(self.selectedCatalogue.id)):
			Catalogue.delete(self.selectedCatalogue.id)
			self.searchCatalogue()
		self.deleteCatalogueBt.config(state=DISABLED)
		self.clearFieldCatalogue()
	# FIN de la gestion du module Catalogue ------------------------------------------------------------------------------------------------------------------------

	# DEBUT de la gestion du module LineCatalogue ------------------------------------------------------------------------------------------------------------------
	def clearFieldLineCatalogue(self):
		# Mise a zéro des champs
		self.lineCatalogueValues[0].set("")
		self.lineCatalogueValues[1].set("")
		self.lineCatalogueValues[2].set("")
		self.lineCatalogueValues[3].set("")
		self.lineCatalogueValues[4].set(u"DY")
		self.lineCatalogueUnitCB.selectitem(0)

	def selectLineCatalogue(self, id=0):
		if id != 0:
			result = LineCatalogue.select(LineCatalogue.q.id==id)
			for row in result:
				self.selectedLineCatalogue = row
			self.listObject[1]=self.selectedLineCatalogue.reference
			self.listObject[2]=self.selectedLineCatalogue.tax
			self.lineCatalogueValues[0].set(self.selectedLineCatalogue.reference.code)
			self.lineCatalogueValues[3].set("%.2f" % self.selectedLineCatalogue.tax.rate)
			if self.selectedLineCatalogue.description != None:self.lineCatalogueValues[1].set(self.selectedLineCatalogue.description)
			if self.selectedLineCatalogue.price != None:self.lineCatalogueValues[2].set("%.2f" % self.selectedLineCatalogue.price)
			if self.selectedLineCatalogue.unit != None:self.lineCatalogueValues[4].set(self.selectedLineCatalogue.unit)
			# Affichage du Unit dans la ComboBox
			unit = ((u"DY", 0),(u"BN", 1),(u"WK", 2),(u"D2", 3),(u"W1", 4),(u"W2", 5),(u"W3", 6),(u"W4", 7),(u"M1", 8),(u"SE", 9),(u"HR", 10),(u"PR", 11),(u"UT", 12),) 
			for n in unit:
				if n[0] == self.selectedLineCatalogue.unit: self.lineCatalogueUnitCB.selectitem(n[1])
			# activation du bouton supprimer
			self.deleteLineCatalogueBt.config(state=NORMAL)

	def searchLineCatalogue(self, event=None):
		if self.listLineCatalogue is not None:self.listLineCatalogue.destroy()
		self.listLineCatalogue=Frame(self.listFrame.interior())
		result = LineCatalogue.select(LineCatalogue.q.catalogue==self.listObject[0],orderBy=LineCatalogue.q.description)
		lineValues = [StringVar(),StringVar(),StringVar(),StringVar(),StringVar(),StringVar()]
		for row in result:
			t = Frame(self.listLineCatalogue)
			lineValues[0].set(str(row.id))
			lineValues[1].set(row.reference.code)
			lineValues[2].set(row.description)
			lineValues[3].set("%.2f" % row.price)
			lineValues[4].set("%.2f" % row.tax.rate)
			lineValues[5].set(row.unit)
			Entry(t, textvariable= lineValues[0], width=3, justify=CENTER, state=DISABLED, bd=0, disabledforeground="black", disabledbackground="white").pack(side=LEFT)
			Entry(t, textvariable= lineValues[1], width=26, justify=CENTER, state=DISABLED, bd=0, disabledforeground="black", disabledbackground="white").pack(side=LEFT)
			Entry(t, textvariable= lineValues[2], width=26, state=DISABLED, bd=0, disabledforeground="black", disabledbackground="white").pack(side=LEFT)
			Entry(t, textvariable= lineValues[3], width=10, justify=RIGHT, state=DISABLED, bd=0, disabledforeground="black", disabledbackground="white").pack(side=LEFT)
			Entry(t, textvariable= lineValues[4], width=10, justify=RIGHT, state=DISABLED, bd=0, disabledforeground="black", disabledbackground="white").pack(side=LEFT)
			Entry(t, textvariable= lineValues[5], width=19, justify=CENTER, state=DISABLED, bd=0, disabledforeground="black", disabledbackground="white").pack(side=LEFT)
			myID=Button(t, image=self.imgSearch, command=lambda x=row.id:self.selectLineCatalogue(x), padx=4, pady=1)
			myID.pack(side=RIGHT)
			self.balloon.bind(myID, u"Modifier ou supprimer cette ligne")
			t.pack(side=TOP, fill=X)
			lineValues = [StringVar(),StringVar(),StringVar(),StringVar(),StringVar(),StringVar()]
		self.listLineCatalogue.pack(side=TOP, fill=X)

	def makeLineCatalogue(self):
		bottomFrame = Frame(self)
		leftLCFrame = Frame(bottomFrame, relief=SUNKEN, borderwidth=1)
		lineCatalogueLabels = (u"Référence", u"Déscription", u"Prix HT", u"Taxe", u"Unité")
		self.lineCatalogueValues = [StringVar(),StringVar(),StringVar(),StringVar(),StringVar()]
		lineCatalogueUnitListCB = ( u"par Jour", u"par Nuit", u"Week-end", u"2 nuits", u"1 semaine", u"2 semaines", u"3 semaines", u"4 semaines", u"1 mois", u"Le stage", u"Heure", u"La préstation", u"Unité") 
		count = 0
		p = Frame(leftLCFrame)
		for name in lineCatalogueLabels:
			f = Frame(p)
			if count == 0: # Référence
				Label(f, width=24, text=name).pack(side=TOP)
				t= Frame(f)
				Entry(t, textvariable=self.lineCatalogueValues[count], width=22, state=DISABLED, bd=0, disabledforeground="black").pack(side=LEFT)
				myReference=Button(t, image=self.imgSearch, command=lambda x=self.lineCatalogueValues[count]:self.ctrlListReference(x), padx=4, pady=1)
				myReference.pack(side=LEFT)
				self.balloon.bind(myReference, u"Séléctionner une Référence")
				t.pack(side=TOP)
			elif count == 1: # Déscription
				Label(f, width=24, text=name).pack(side=TOP)
				t= Frame(f)
				Entry(t, textvariable=self.lineCatalogueValues[count], width=22).pack(side=LEFT)
				myDescription=Button(t, image=self.imgNotes, command=lambda x=self.lineCatalogueValues[count]:self.ctrlNotes(x,u"Déscription"), padx=4, pady=1)
				myDescription.pack(side=LEFT)
				self.balloon.bind(myDescription, u"Détails de la Description")
				t.pack(side=TOP)
			elif count == 2: # Price
				Label(f, width=10, text=name).pack(side=TOP)
				Entry(f, textvariable=self.lineCatalogueValues[count], width=10, justify=RIGHT).pack(side=TOP)
			elif count == 3: # Tax
				Label(f, width=9, text=name).pack(side=TOP)
				t= Frame(f)
				Entry(t, textvariable=self.lineCatalogueValues[count], width=7, state=DISABLED, bd=0, disabledforeground="black", justify=RIGHT).pack(side=LEFT)
				myTax=Button(t, image=self.imgSearch, command=lambda x=self.lineCatalogueValues[count]:self.ctrlListTax(x), padx=4, pady=1)
				myTax.pack(side=LEFT)
				self.balloon.bind(myTax, u"Séléctionner une Taxe")
				t.pack(side=TOP)
			elif count == 4: #Unit
				Label(f, width=14, text=name).pack(side=TOP)
				self.lineCatalogueUnitCB=Pmw.ComboBox(f, selectioncommand=self.lineCatalogueUnit, scrolledlist_items=lineCatalogueUnitListCB, listheight=140)
				self.lineCatalogueUnitCB._entryfield._entryFieldEntry.config( width=14)
				self.lineCatalogueUnitCB.pack(side=TOP)
				self.lineCatalogueUnitCB.selectitem(0)
				self.lineCatalogueValues[count].set(u"NO")
			else:
				pass
			f.pack(side=LEFT, fill=X)
			count += 1
		f = Frame(p)
		self.saveLineCatalogueBt=Button(f, image=self.imgSave, command=self.createLineCatalogue)
		self.saveLineCatalogueBt.bind("<Return>", self.createLineCatalogue)
		self.saveLineCatalogueBt.pack(side=LEFT)
		self.balloon.bind(self.saveLineCatalogueBt, u"Enregistrer")
		self.deleteLineCatalogueBt=Button(f, image=self.imgDelete, command=self.deleteLineCatalogue, state=DISABLED)
		self.deleteLineCatalogueBt.bind("<Return>", self.deleteLineCatalogue)
		self.deleteLineCatalogueBt.pack(side=LEFT)
		self.balloon.bind(self.deleteLineCatalogueBt, u"Supprimer")
		f.pack(side=LEFT, fill=X)
		p.pack(side=TOP, fill=X)
		self.listFrame= Pmw.ScrolledFrame(leftLCFrame)
		self.listLineCatalogue=None
		self.listFrame.pack(side=TOP, fill=BOTH)
		leftLCFrame.pack(side=TOP, fill=X)
		bottomFrame.pack(side=TOP, fill=X)

	def ctrlCalendar(self,field):
		CalendarGUI(field=field, log=self.log, path=self.path)

	def ctrlNotes(self,field,title):
		NotesGUI(field=field,title=title, log=self.log, path=self.path)

	def ctrlListReference(self,field):
		ReferenceListGUI(balloon=self.balloon, field=field, index=1, listObject=self.listObject, log=self.log, path=self.path)

	def ctrlListTax(self,field):
		TaxListGUI(balloon=self.balloon, field=field, index=2, listObject=self.listObject, log=self.log, path=self.path)

	def lineCatalogueUnit(self, value):
		unit = ((u"DY", u"par Jour"),(u"BN", u"par Nuit"),(u"WK", u"Week-end"),(u"D2", u"2 nuits"),(u"W1", u"1 semaine"),(u"W2", u"2 semaines"),(u"W3", u"3 semaines"),(u"W4", u"4 semaines"),(u"M1", u"1 mois"),(u"SE", u"Le stage"),(u"HR", u"Heure"),(u"PR", u"La préstation"),(u"UT", u"Unité"),) 
		for n in unit:
			if n[1] == value: self.lineCatalogueValues[4].set(n[0])

	def verifyLineCatalogue(self):
		if self.lineCatalogueValues[0].get() == "":
			showerror(u"Erreur de saisie", u"Le champ Référence est obligatoire !\nMerci de le compléter.")
			return False
		elif self.lineCatalogueValues[1].get() == "":
			showerror(u"Erreur de saisie", u"Le champ Déscription est obligatoire !\nMerci de le compléter.")
			return False
		elif self.lineCatalogueValues[2].get() == "":
			showerror(u"Erreur de saisie", u"Le champ Prix est obligatoire !\nMerci de le compléter.")
			return False
		elif self.lineCatalogueValues[3].get() == "":
			showerror(u"Erreur de saisie", u"Le champ Taxe est obligatoire !\nMerci de le compléter.")
			return False
		elif self.lineCatalogueValues[4].get() == "":
			showerror(u"Erreur de saisie", u"Le champ Unité est obligatoire !\nMerci de le compléter.")
			return False
		else:
			return True

	def createLineCatalogue(self, event=None):
		if self.verifyLineCatalogue():
			if  self.deleteLineCatalogueBt.config()["state"][4] == "normal":
				self.modifyLineCatalogue()
			else:
				if askyesno(u"Enregistrement", u"Souhaitez-vous enregistrer %s comme une nouvelle ligne du catalogue ?\n" % self.lineCatalogueValues[1].get()):
					LineCatalogue(catalogue=self.listObject[0],
						reference=self.listObject[1],
						description=self.lineCatalogueValues[1].get().encode("utf-8"),
						price=self.lineCatalogueValues[2].get().encode("utf-8"),
						tax=self.listObject[2],
						unit=self.lineCatalogueValues[4].get().encode("utf-8"),
						createDate=datetime.datetime.now()
					)
					self.searchLineCatalogue()
				self.clearFieldLineCatalogue()

	def modifyLineCatalogue(self, event=None):
		if askyesno(u"Modifier", u"Souhaitez-vous modifier la ligne %s du catalogue ?" % str(self.selectedLineCatalogue.id)):
			self.selectedLineCatalogue.reference=self.listObject[1]
			self.selectedLineCatalogue.description=self.lineCatalogueValues[1].get().encode("utf-8")
			self.selectedLineCatalogue.price=self.lineCatalogueValues[2].get().encode("utf-8")
			self.selectedLineCatalogue.tax=self.listObject[2]
			self.selectedLineCatalogue.unit=self.lineCatalogueValues[4].get().encode("utf-8")
			self.searchLineCatalogue()
		self.deleteLineCatalogueBt.config(state=DISABLED)
		self.clearFieldLineCatalogue()

	def deleteLineCatalogue(self, event=None):
		if askyesno(u"Suppression", u"Souhaitez-vous supprimer la ligne %s du catalogue ?\nCette opération est irréversible !" % str(self.selectedLineCatalogue.id)):
			LineCatalogue.delete(self.selectedLineCatalogue.id)
			self.searchLineCatalogue()
		self.deleteLineCatalogueBt.config(state=DISABLED)
		self.clearFieldLineCatalogue()
	# FIN de la gestion du module LineCatalogue --------------------------------------------------------------------------------------------------

#~ class ListGUI(Toplevel):
    #~ def __init__(self, parent=None, balloon=None, field=None, index=None):
        #~ Toplevel.__init__(self, parent)
        #~ self.parent=parent
        #~ self.grab_set() 
        #~ self.transient(self.master)
        #~ self.resizable(width=False, height=False)
        #~ self.title(u"Liste des Articles")
        #~ self.balloon=balloon
        #~ self.field=field
        #~ self.index=index
        #~ self.makeListItem()